package com.wangshb.upms.core.spring.security;

import com.wangshb.upms.mapper.UpmsRolePermissionMapper;
import com.wangshb.upms.model.PermissionForRoleModel;
import com.wangshb.upms.service.UpmsUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;


@Component
@Slf4j
public class DynamicUrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource, InitializingBean {


    @Resource
    private UpmsRolePermissionMapper upmsRolePermissionMapper;


    private Map<String, List<String>> requestUrlMap;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

        FilterInvocation fi = (FilterInvocation) object;
        String url = fi.getRequestUrl();

        if (requestUrlMap.containsKey(url)) {
            List<String> roleList = requestUrlMap.get(url);
            if (CollectionUtils.isNotEmpty(roleList)) {
                return SecurityConfig.createList(ArrayUtils.toStringArray(roleList.toArray()));
            }
        }

        return SecurityConfig.createList(url);
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }


    /**
     *  加载权限资源
     */
    @Override
    public void afterPropertiesSet() throws Exception {

        List<PermissionForRoleModel> permissionForRoleModels = upmsRolePermissionMapper.loadAllPermissionForRole();
        if (null == permissionForRoleModels || permissionForRoleModels.size() == 0) {
            requestUrlMap = new HashMap<>(0);
        }
        else {
            requestUrlMap = new HashMap<>(permissionForRoleModels.size() / 2);
            permissionForRoleModels.stream().filter(model -> StringUtils.isNotBlank(model.getUrl()) && CollectionUtils.isNotEmpty(model.getAccessRoleList()))
                    .forEach(model -> {
                        if (!requestUrlMap.containsKey(model.getUrl())) {
                            requestUrlMap.put(model.getUrl(), new ArrayList<>());
                        }
                        requestUrlMap.get(model.getUrl()).addAll(model.getAccessRoleList());
                    });
        }

        log.info("共加载 {} 个权限信息.", requestUrlMap.size());
    }
}
